<template>
    <div class="main p-4">
        <div class="title f-16 font-bold mb-4">生成模拟试卷</div>
        <el-form ref="formRef" :model="formData" label-width="100" class="form">
            <el-form-item label="试卷名称" prop="name" required>
                <el-input v-model="formData.name" placeholder="请输入" />
            </el-form-item>
            <el-form-item label="满分" required>
                <el-input :value="fullScore" disabled placeholder="自动计算" />
            </el-form-item>
            <el-form-item label="难度" prop="difficulty">
                <el-input-number v-model="formData.difficulty" :min="1" placeholder="请输入数字" />
            </el-form-item>
            <el-form-item label="用时(分钟)" prop="useTime">
                <el-input-number v-model="formData.useTime" placeholder="请输入" />
            </el-form-item>
            <el-form-item label="大题" prop="paperQuestionsTypeDtos">
                <div class="mt-5 w-full">
                    <Question
                    v-for="(item, i) in formData.paperQuestionsTypeDtos"
                    :key="i"
                    :i="i"
                    :questionsTypeList="questionsTypeList"
                    v-model="formData.paperQuestionsTypeDtos[i]"
                    :topic-list="topicList"
                    :categoryList="categoryList"
                    :ref="(el: any) => addQuestionRef(el, item.uid)"
                    @delete="deleteQuestion(item)"
                    />
                    <el-button @click="addBigQuestion" plain type="primary" class="w-full mt-4">+ 添加大题</el-button>
                </div>
            </el-form-item>
            <div class="sticky-bottom flex items-center justify-end">
                <el-button @click="cancel">取消</el-button>
                <el-button @click="submit" type="primary">保存</el-button>
            </div>
        </el-form>
    </div>
</template>

<script setup lang="ts">
import request from '@/Utils/request';
import { computed, onActivated, reactive, ref, type VNodeRef } from 'vue';
import { useRoute } from 'vue-router';
import Question from './Children/Question.vue';
import { createUuid, getText } from '@/Utils/utils';
import type { GeneratePaperSmallQuestion, TopicTypeNumber } from '@/Utils/type';
import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus';
import router from '@/Router';

interface GeneratePaperSmallQuestionItem extends GeneratePaperSmallQuestion {
    uuid: string;
}

interface Questions {
    name: string;
    questionsType: TopicTypeNumber;
    paperQuestionsTypeDetailDtos: GeneratePaperSmallQuestionItem[];
    uid: string;
}

type QuestionType = InstanceType<typeof Question>;

interface QuestionRef {
    [propName: string]: QuestionType;
};

const formRef = ref<FormInstance>();

const route = useRoute();

const categoryList = ref<any[]>([]);

// 获取分类列表
const getCategoryList = async () => {
    try {
        categoryList.value = await request({
            url: '/paper/category/list',
            method: 'post'
        });
    } catch (error) {
        
    }
};

const questionsTypeList = ref([
    {
        id: 1,
        label: '填空题'
    },
    {
        id: 2,
        label: '选择题'
    },
    {
        id: 3,
        label: '计算题'
    },
    {
        id: 4,
        label: '应用题'
    },
    {
        id: 5,
        label: '判断题'
    }
]);

const formData = reactive({
    difficulty: 1,
    fullScore: 100,
    id: 0,
    name: '',
    useTime: 60,
    paperType: 6,
    paperQuestionsTypeDtos: <Questions[]>[
        {
            name: '',
            questionsType: 1,
            uid: createUuid(),
            paperQuestionsTypeDetailDtos: [
                {
                    categoryId: '',
                    difficulty: 1,
                    num: 1,
                    score: 3,
                    uuid: createUuid(),
                }
            ]
        }
    ],
});

const topicListData = ref([]);

const questionRefs = reactive<QuestionRef>({});

const topicList = computed(() => topicListData.value.map((item: any) => {
    return {
        value: item.id,
        label: getText(item.content),
        type: item.questionsType
    }
}));

// 满分，自动计算
const fullScore = computed(() => formData.paperQuestionsTypeDtos.reduce((total: number, item) => {
    const questionsIdList = item.paperQuestionsTypeDetailDtos || [];
    if (questionsIdList.length > 0) {
        total += questionsIdList.reduce((questionsTotal: number, item) => {
            questionsTotal += item.num * item.score;
            return questionsTotal;
        }, 0);
    }
    return total;
}, 0));

const addQuestionRef = (el: QuestionType, key: string) => {
    questionRefs[key] = el;
    return el as unknown as VNodeRef;
};

// 点击删除大题
const deleteQuestion = async (item: Questions) => {
    try {
        await ElMessageBox.confirm(
            '确认删除试题吗？',
            '提示',
            {
                confirmButtonText: '确定删除',
                cancelButtonText: '取消',
                type: 'warning',
            }
        );
        const index = formData.paperQuestionsTypeDtos.findIndex(question => item.uid === question.uid);
        if (index > -1) formData.paperQuestionsTypeDtos.splice(index, 1);
        ElMessage({
            message: '删除成功',
            type: 'success'
        });
    } catch (error) {
        
    }
};

// 点击添加大题
const addBigQuestion = () => {
    formData.paperQuestionsTypeDtos.push({
        name: '',
        questionsType: 1,
        uid: createUuid(),
        paperQuestionsTypeDetailDtos: [
            {
                categoryId: '',
                difficulty: 1,
                num: 1,
                score: 3,
                uuid: createUuid(),
            }
        ]
    });
};

// 点击取消
const cancel = async () => {
    try {
        await ElMessageBox.confirm(
            '确定取消？',
            '提示',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            }
        );
        router.back();
    } catch (error) {
        
    }
};

// 点击提交
const submit = async () => {
    try {
        await validate();
        await ElMessageBox.confirm(
            '确定保存？',
            '提示',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            }
        );
        await request({
            method: 'post',
            url: '/paper/generatepaper',
            contentTypeIsForm: false,
            showLoading: {},
            errorToast: true,
            data: {
                ...formData,
                fullScore: fullScore.value,
                paperType: 6,
                paperQuestionsTypeDtos: formData.paperQuestionsTypeDtos.map(item => {
                    return {
                        ...item,
                        fullScore: item.paperQuestionsTypeDetailDtos.reduce((total: number, topic) => {
                            total += topic.score * topic.num;
                            return total;
                        }, 0)
                    }
                })
            }
        });
        ElMessage({
            message: '保存成功',
            type: 'success'
        });
        router.back();
    } catch (error) {
        
    }
};

// 校验整个表单
const validate = () => {
    return new Promise(async (resolve, reject) => {
        try {
            let result = true;
            const resArr = await Promise.allSettled([
                formRef.value?.validate(),
                ...Object.keys(questionRefs).map(key => questionRefs[key]!.validate())
            ]);
            resArr.forEach(res => {
                if (res.status === 'rejected' || res.value === false) {
                    result = false;
                }
            });
            if (result) {
                resolve(true);
            } else {
                reject(false);
            }
        } catch (error) {
            reject(false);
        }
    });
};

onActivated(() => {
    getCategoryList();
});
</script>

<style scoped lang="scss">
.main {
    .sticky-bottom {
        height: 60px;
        background-color: rgba(255,255,255,0.9);
    }
    .form {
        width: 1000px;
    }
}
</style>